﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Twipler.App.Parse.Code;
using Twipler.App.Render;
using Twipler.App.DataDoc;
using Twipler.Data.Entity.Twipler;
using Twipler.WebApp;

namespace Settings.Sandbox
{
    [RequireUser(VisitorRole.Registered)]
    public partial class DataDocTest : System.Web.UI.Page
    {
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                MethodInfo method = GetSelectedMethodInfo();
                if (method == null)
                    return;

                DataDocList ret = method.Invoke(null, GetParametersFromRepeater(method)) as DataDocList;
                if (ret == null)
                {
                    litOut.Text = "Did not return datadoc";
                    return;
                }

                StringBuilder html = new StringBuilder();
                ret.DebugRender(html, 0);
                litOut.Text = html.ToString();
            }
            catch (Exception ex)
            {
                litOut.Text = "Exception: " + ex.Message;
            }

        }

        private void PopulateCallableMethodsDropdown()
        {
            IEnumerable<MethodInfo> methodInfo = GetCallableMethods()
                                                .Where(type => type.ReturnType == typeof(IDataDoc));


            // Create list like "DirectMessages.Send(string,string)" by removing ReturnType prefix from mi and prefix with classname
            var methods = from mi in methodInfo
                          select new KeyValuePair<string,string>(
                              mi.DeclaringType.Name + "." + mi.ToString().Substring(mi.ToString().IndexOf(' ') + 1),
                              mi.GetHashCode().ToString());

            drpList.Items.Clear();
            drpList.DataSource = methods;
            drpList.DataTextField = "Key";
            drpList.DataValueField = "Value";
            drpList.DataBind();

            drpList.SelectedIndex = 0;
            drpList_Changed(null, null);
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                PopulateCallableMethodsDropdown();
        }

        private static IEnumerable<MethodInfo> _callable;
        public static IEnumerable<MethodInfo> GetCallableMethods()
        {
            if (_callable == null)
                _callable =  Assembly.GetAssembly(typeof(ICallableClass)).GetTypes()
                    .Where(cls => typeof(ICallableClass).IsAssignableFrom(cls))
                    .SelectMany(type => type.GetMethods(BindingFlags.Static | BindingFlags.Public));

            return _callable;
        }

        protected void drpList_Changed(object sender, EventArgs e)
        {
            MethodInfo method = GetSelectedMethodInfo();
            if (method == null)
                return;

            rptParams.DataSource = method.GetParameters();
            rptParams.DataBind();
        }

        private MethodInfo GetSelectedMethodInfo()
        {
            return _callable.FirstOrDefault(mi => mi.GetHashCode().ToString() == drpList.SelectedValue);
        }

        protected void rptParams_ItemBound(object sender, RepeaterItemEventArgs e)
        {
            if ((e.Item.ItemType != ListItemType.Item) && (e.Item.ItemType != ListItemType.AlternatingItem))
                return;
        
            Literal litType = (Literal) e.Item.FindControl("litType");
            litType.Text = ((ParameterInfo) e.Item.DataItem).ParameterType.Name;
        }

        private object[] GetParametersFromRepeater(MethodInfo methodInfo)
        {
            if (rptParams.Items.Count == 0)
                return null;

            List<object> values = new List<object>();

            for (int i = 0; i < rptParams.Items.Count; i++ )
            {
                TextBox txtValue = (TextBox) rptParams.Items[i].FindControl("txtValue");
            
                object obj = txtValue.Text;

                if (methodInfo.GetParameters()[i].ParameterType == typeof(Int32))
                    obj = Convert.ToInt32(obj);

                if (methodInfo.GetParameters()[i].ParameterType == typeof(Int64))
                    obj = Convert.ToInt64(obj);

                if (methodInfo.GetParameters()[i].ParameterType == typeof(Double))
                    obj = Convert.ToDouble(obj);

                values.Add(obj);
            }

            return values.ToArray();
        }
    }
}